package hu.dobrosi.dinkycam.j2me.forms;

import hu.dobrosi.dinkycam.j2me.DinkycamApp;
import hu.dobrosi.dinkycam.j2me.Labels;
import hu.dobrosi.util.StringUtil;

import java.io.IOException;
import java.util.Hashtable;

import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.DeviceClass;
import javax.bluetooth.DiscoveryAgent;
import javax.bluetooth.DiscoveryListener;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.ServiceRecord;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.List;
import javax.microedition.lcdui.TextField;

public class BluetoothDeviceList extends List implements DiscoveryListener,
		CommandListener {
	private DiscoveryAgent agent;
	private DinkycamApp app;
	private Command cmdOk;
	private Hashtable devices;
	private Command cmdBack;
	private boolean standalone;
	private TextField field;
	private boolean discoveryFinished;
	private BluetoothDeviceListResponseHandler responseHandler;

	public BluetoothDeviceList(int listType, DinkycamApp app, String title,
			TextField field, BluetoothDeviceListResponseHandler responseHandler) {
		super(title, listType);
		this.app = app;
		this.field = field;
		this.responseHandler = responseHandler;
		buildGUI();
	}

	public void buildGUI() {
		addCommand(cmdOk = new Command(Labels.OK.toString(), Command.ITEM, 1));
		addCommand(cmdBack = new Command(Labels.BACK.toString(), Command.BACK,
				1));
		setCommandListener(this);
	}

	public void discovery() {
		field.setString("");
		discovery(false);
	}

	public void discovery(boolean standalone) {
		discoveryFinished = false;
		this.standalone = standalone;
		if (!standalone) {
			app.showInfo(Labels.SEARCHING_BT_DEVICES.toString());
		}
		LocalDevice ldevice;
		try {
			devices = new Hashtable();
			deleteAll();
			ldevice = LocalDevice.getLocalDevice();
			agent = ldevice.getDiscoveryAgent();
			agent.startInquiry(DiscoveryAgent.GIAC, this);
		} catch (BluetoothStateException e) {
			app.showError(this, "discovery", e);
			e.printStackTrace();
		}
	}

	public void commandAction(Command c, Displayable s) {
		if (c == cmdOk || c == cmdBack) {
			field.setString("" + geSelectedDeviceAddress());
			app.showSettings();
			if (responseHandler != null) {
				responseHandler.handle();
			}
		}
	}

	public void deviceDiscovered(RemoteDevice arg0, DeviceClass arg1) {
		try {
			String name = arg0.getFriendlyName(true);
			String address = arg0.getBluetoothAddress();
			app.showInfo(address);
			devices.put(new Integer(devices.size()), address);
			append(name == null ? address : name, null);
			// UUID[] uuidSet = new UUID[1];
			// uuidSet[0] = new UUID(0x1101);
			// int[] attrSet = { 0x0100, 0x0003, 0x0004 };
			// agent.searchServices(attrSet, uuidSet, arg0, this);
		} catch (BluetoothStateException e) {
			app.showError(this, "deviceDiscovered", e);
		} catch (IOException e) {
			app.showError(this, "deviceDiscovered", e);
		}
	}

	public void inquiryCompleted(int arg0) {
		if (!standalone) {
			app.showInfo(Labels.SEARCHING_FINISHED.toString() + " (" + arg0
					+ ")");
		}
		discoveryFinished = true;
	}

	public void serviceSearchCompleted(int arg0, int arg1) {

	}

	public void servicesDiscovered(int arg0, ServiceRecord[] arg1) {
	}

	private Object getDeviceAddress(int key) {
		return devices.get(new Integer(key));
	}

	private Object geSelectedDeviceAddress() {
		String res = "";
		boolean[] selectedArray = new boolean[size()];
		getSelectedFlags(selectedArray);
		for (int i = 0; i < size(); i++) {
			if (selectedArray[i]) {
				res = "" + getDeviceAddress(i);
			}
		}
		return res;
	}

	public boolean findDevice(String addr) {
		discovery(true);
		addr = addr.toUpperCase();
		boolean res = false;
		try {
			while (!discoveryFinished) {
				StringUtil.logger.print("f");
				Thread.sleep(500);
				for (int i = 0; i < size(); i++) {
					if (addr.indexOf(("" + getDeviceAddress(i)).toUpperCase()) >= 0) {
						res = true;
					}
				}
			}
		} catch (InterruptedException e) {
			StringUtil.logger.clear();
			StringUtil.logger.print(e);
		}
		return res;
	}
}
